home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
9-Digit Zip Code Directory
/
9-Digit Zip Code Directory (American Business Information) (ABIZIP-12).ISO
/
z4src.zip
/
BSPRINT.C
< prev
next >
Wrap
C/C++ Source or Header
|
1995-09-12
|
25KB
|
855 lines
//----------------------------------------------------------------------------
// MODULE DESCRIPTION
//
// Module: bsprint.c
// Title: Base library
// Notice: John M. Weeder
// Copyright (c) 1993. All rights reserved.
// This module contains proprietary information and should be
// treated as confidential.
//
//----------------------------------------------------------------------------
// MAINTENANCE HISTORY
//
// $Workfile$
// $Revision$
// $Author$
// $Date$
// $Log$
//
//----------------------------------------------------------------------------
// MODULE NARRATIVE
//
//
// This module contains code to print a text file to the printer output
// device for the current operating system.
//
// The input text file must contain ASCII printable characters. Control
// strings are inserted using the <ESC> (27 or 0x1B). Control string must
// begin and end with an escape character. Control strings are also terminated
// at the end of a line. If a control string ends at the end of a line but
// does not have a terminating <ESC> character, then the line feed is
// suppressed.
// The control string consists of a command followed by an optional equal
// ('=') sign and the command arguments.
// For example:
// <ESC>command=arguments<ESC>
//
// The following commands are currently recognized:
//
// The following commands are planned for implementation:
// TABS = nn nn nn nn Tab stops
// Tab stops are printer and OS dependent.
// FOOTER = footer text Header
// HEADER = header text Footer
// Both the header and the footer may
// contain option codes to fill in the
// date/time/page.
// &p Page Number
// &d Date
// &t Time
//
// Form feeds are recognized and converted into automatic page breaks.
// Tabs are recognized and converted according to the current tab stop
// settings.
//
// Line length (including control characters) must not exceed MAX_PRINT_BUF
// characters.
//
// The windows version of this module expects to find a dialog resource
// named 'AbortPrintDlg'
//
// This module is not re-entrant and cannot be used in a multi-thread
// environment.
//
//
// The code in this module should be written entirely in C.
// Do not use any C++ constructs.
//
// This module is portable to:
// DOS 3.X+
// MS Windows 3.X+
// OS/2 2.X+
// OS/2 2.0 PM
// SCO UNIX.
//
// The following compilers are supported:
// MSC 6.0A
// MSC/C++ 7.0
// Borland C++ 3.1 for DOS
// Borland C++ 1.0 for OS/2 2.X
// SCO UNIX cc
//
//----------------------------------------------------------------------------
#include <bs.h>
//----------------------------------------------------------------------------
// Constants
//----------------------------------------------------------------------------
#if OS_DOS || OS_WINDOWS
#define MAX_PRINT_BUF (2048)
#define MAX_TABS (20)
typedef struct PRT // Globals for printer routines
{
FLAG16 fs; // Flags
PFNPRINT pfnprint; // Printer callback function
PCSZ pcszName; // Print job name
USHORT usPort; // Printer port (DOS only)
BOOL fCommandPending; // Escape command pending
BOOL fCRPending; // Carriage return pending
BOOL fAbort; // Abort flag
CHAR szFile[MAX_PATH]; // Spool file name
HF hf; // Input file handle
//LONG lSize; // Input file length
ULONG lSize;
FPOS fpos; // Current position in input file
BOOL fError; // Error flag
BYTE bBuf1[MAX_PRINT_BUF+1]; // Input buffer
PBYTE pb1; // Next character to use in buffer
SIZET cBuf1; // Amount of data in buffer
BYTE bBuf2[MAX_PRINT_BUF+1]; // Output for current line of text
PBYTE pb2; // Next character to use in buffer
BYTE bBuf3[MAX_PRINT_BUF+1]; // Output for current command
PBYTE pb3; // Next character to use in buffer
#if OS_WINDOWS
PRINTDLG pd; // Print dialog data
HWND hAbortDlgWnd; // Cancel dialog handle
DLGPROC lpAbortDlg; // Cancel dialog procedure
FARPROC lpAbortProc; // Printing abort procedure
HANDLE hHourGlass; // Hour glass cursor
HANDLE hSaveCursor; // Current cursor handle
HDC hPr; // Handle for printer device context
TEXTMETRIC textmetric; // Information about character size
INT iLineSpace; // Spacing between lines
INT iHorzSize; // Horizaontal page size
INT iVertSize; // Vertical page size
INT iTop; // Top of next line
INT iStatus; // Printer status
BOOL fPagePending;
#endif
} PRT;
BASETYPE(PRT);
#endif
//----------------------------------------------------------------------------
// Globals
//----------------------------------------------------------------------------
#if OS_DOS || OS_WINDOWS
static PPRT _pprt = NULL;
#endif
//----------------------------------------------------------------------------
// Prototypes
//----------------------------------------------------------------------------
#if OS_DOS
static USHORT FN_E DosPrintStatus(USHORT);
static BOOL FN_E PrintFFDos(PPRT);
static BOOL FN_E PrintTextDos(PPRT);
#endif
#if OS_DOS || OS_WINDOWS
static BOOL FN_E PrintBuffer(PPRT);
static BOOL FN_E PrintCommand(PPRT);
static PPRT FN_E PrintInitialize(PCSZ, FLAG16, PFNPRINT, PCSZ);
static BOOL FN_E PrintProcess(PPRT);
static BOOL FN_E PrintTerminate(PPRT);
static BOOL FN_E PrintText(PPRT, BOOL);
#endif
#if OS_WINDOWS
static BOOL FN_E PrintFFWindows(PPRT);
static BOOL FN_E PrintTextWindows(PPRT);
static int FN_W WindowsAbortDlg(HWND, unsigned, WORD, LONG);
static int FN_W WindowsAbortProc(HDC, int);
static HDC FN_L WindowsGetPrinterDC(PPRT);
#endif
//----------------------------------------------------------------------------
// Description: Print a single line.
// This function is not valid under Windows!
// Parameters: pcsz Line to print.
// If null, return status.
// Returns:
//----------------------------------------------------------------------------
#if OS_DOS
USHORT FN_E DosPrintLine(PCSZ pcsz, USHORT usPort)
{
USHORT usStatus = 0;
usStatus = DosPrintStatus(_bios_printer(_PRINTER_STATUS, usPort, 0));
if (pcsz != NULL)
{
while (pcsz[0] && usStatus == 0)
{
usStatus = DosPrintStatus(_bios_printer(_PRINTER_WRITE, usPort, pcsz[0]));
pcsz++;
}
}
return usStatus;
}
#endif
//----------------------------------------------------------------------------
// Description: Print a file
// Parameters: pcsz Line to print.
// If null, return status.
// Returns:
//----------------------------------------------------------------------------
#if OS_DOS
static USHORT FN_E DosPrintStatus(USHORT usStatus)
{
usStatus &= ~(PRT_ERR_NO_ACK|PRT_ERR_BUSY);
return usStatus ^ PRT_ERR_NOT_SELECTED;
}
#endif
//----------------------------------------------------------------------------
// Description:
// Parameters:
// Returns: TRUE if successful.
//----------------------------------------------------------------------------
#if OS_DOS || OS_WINDOWS
static BOOL FN_E PrintBuffer(PPRT pprt)
{
pprt->pb1 = pprt->bBuf1; // Setup pointer to buffer
for (; (SIZET)(pprt->pb1 - pprt->bBuf1) < pprt->cBuf1 && !pprt->fAbort; ++pprt->pb1)
{
if (*pprt->pb1 == PRT_ESCAPE) // Printer escape
{
if (pprt->fCommandPending) // If command is pending, process it
{
if (!PrintCommand(pprt))
return FALSE;
}
else // Else, start a new command
pprt->fCommandPending = TRUE;
}
else if (*pprt->pb1 == '\t') // Tab
{
Assert((SIZET)(pprt->pb3 - pprt->bBuf3) < MAX_PRINT_BUF);
*pprt->pb3++ = ' ';
}
else if (*pprt->pb1 == '\f')
{
if (pprt->fCommandPending) // If a command is pending, process it
if (!PrintCommand(pprt))
return FALSE;
if (!PrintText(pprt, FALSE)) // Flush text on this page
return FALSE;
#if OS_DOS
if (!PrintFFDos(pprt)) // Goto next page
return FALSE;
#elif OS_WINDOWS
if (!PrintFFWindows(pprt))
return FALSE;
#endif
}
else if (*pprt->pb1 == '\r' // End of line. Flush command buffer
|| *pprt->pb1 == '\n') // and text buffer as needed
{
if (!pprt->fCRPending // Make sure this is not part of a
|| *pprt->pb1 == '\r') // CR/LF sequence in a DOS file
{
if (pprt->fCommandPending) // If a command is pending, process it
{ // and suppress line feed
if (!PrintCommand(pprt))
return FALSE;
} // Process any text
else if (!PrintText(pprt, TRUE))
return FALSE;
}
}
else if (iscntrl(*pprt->pb1)) // Other control character?
{
; // Ignore character
}
else if (pprt->fCommandPending) // Append byte to command buffer
{
Assert((SIZET)(pprt->pb3 - pprt->bBuf3) < MAX_PRINT_BUF);
*pprt->pb3++ = *pprt->pb1;
}
else // Append byte to text buffer
{
Assert((SIZET)(pprt->pb2 - pprt->bBuf2) < MAX_PRINT_BUF);
*pprt->pb2++ = *pprt->pb1;
}
pprt->fCRPending = (*pprt->pb1 == '\r');
}
return TRUE;
}
#endif
//----------------------------------------------------------------------------
// Description:
// Parameters:
// Returns: TRUE if successful.
//----------------------------------------------------------------------------
#if OS_DOS || OS_WINDOWS
static BOOL FN_E PrintCommand(PPRT pprt)
{
static PCSZ apcsz[] = // List of valid commands
{
"command",
NULL
};
PSZ psz1, psz2;
SIZET i;
*pprt->pb3 = '\0'; // Add a null terminator to the buffer
psz1 = (PSZ)pprt->bBuf3;
psz2 = strchr(psz1, '=');
if (psz2 != NULL)
{
*psz2 = '\0'; // Replace '=' with a null and point
psz2++; // to the arguments
}
else
psz2 = ""; // No arguments
strtrim(psz1); // Clean up the string
for (i = 0; apcsz[i]; ++i) // Find command
if (stricmp(psz1, apcsz[i]) == 0)
break;
switch (i)
{
case 0:
break;
default: // Invalid
Log(LOG_LOW, "Invalid print spool command, '%s'.", psz1);
break;
}
pprt->fCommandPending = FALSE; // Reset for next command
pprt->pb3 = pprt->bBuf3;
return TRUE;
}
#endif
//----------------------------------------------------------------------------
// Description: Print a file.
// Parameters: pcszFile Name of file to print.
// File is searched for in the directories
// specified by the 'TEMP' environment variable.
// Default extension is PRN
// fs Flags:
// See header file (bsproto.h)
// pfnprint Printer callback function.
// This function takes a single parameter which is
// the current printer error.
// This function should return TRUE to continue
// printing or FALSE to abort.
// pcszName Print job name or NULL
// Returns: TRUE if successful.
//----------------------------------------------------------------------------
BOOL FN_E PrintFile(PCSZ pcszFile, FLAG16 fs, PFNPRINT pfnprint, PCSZ pcszName)
{
#if OS_DOS || OS_WINDOWS
PPRT pprt;
if (pcszFile == NULL || !pcszFile[0])
return TRUE;
// Initialize for printing
pprt = PrintInitialize(pcszFile, fs, pfnprint, pcszName);
if (pprt == NULL)
return FALSE;
if (!pprt->fError) // Process file
PrintProcess(pprt);
return PrintTerminate(pprt); // Clean up
#else
NOTUSED(fs);
NOTUSED(pcszFile);
NOTUSED(pfnprint);
NOTUSED(pcszName);
return FALSE;
#endif
}
//----------------------------------------------------------------------------
// Description:
// Parameters:
// Returns: TRUE if successful.
//----------------------------------------------------------------------------
#if OS_DOS || OS_WINDOWS
static PPRT FN_E PrintInitialize(PCSZ pcszFile, FLAG16 fs, PFNPRINT pfnprint, PCSZ pcszName)
{
PPRT pprt;
FLAG16 fsFile;
//
// Allocate space for globals
//
pprt = (PPRT)MemAllocZero(sizeof(PRT));
if (pprt == NULL)
{
ErrorNoMem();
return NULL;
}
//
// Initialize variables
//
pprt->fs = fs;
pprt->pfnprint = pfnprint;
pprt->hf = -1;
pprt->pcszName = pcszName ? pcszName: "unknown";
if (BTEST(pprt->fs, PRT_LPT2))
pprt->usPort = 1;
else if (BTEST(pprt->fs, PRT_LPT3))
pprt->usPort = 2;
else if (BTEST(pprt->fs, PRT_LPT4))
pprt->usPort = 3;
//
// Store windows globals
//
#if OS_WINDOWS
pprt->hHourGlass = LoadCursor(NULL, IDC_WAIT);
pprt->hSaveCursor = SetCursor(pprt->hHourGlass);
pprt->pd.lStructSize = sizeof(PRINTDLG);
pprt->pd.hwndOwner = NULL;
pprt->pd.hDevMode = NULL;
pprt->pd.hDevNames = NULL;
pprt->pd.Flags = (DWORD)(PD_RETURNDC|PD_NOSELECTION|PD_NOPAGENUMS|PD_USEDEVMODECOPIES);
pprt->pd.nCopies = 1;
pprt->hPr = WindowsGetPrinterDC(pprt);
if (!pprt->hPr)
goto ERROR_EXIT;
#if COMPILE_DLL
pprt->lpAbortDlg = (DLGPROC)WindowsAbortDlg;
pprt->lpAbortProc = (FARPROC)WindowsAbortProc;
#else
pprt->lpAbortDlg = (DLGPROC)MakeProcInstance((FARPROC)WindowsAbortDlg, WindowsInstance());
pprt->lpAbortProc = MakeProcInstance((FARPROC)WindowsAbortProc, WindowsInstance());
#endif
Escape(pprt->hPr, SETABORTPROC, 0, (LPSTR)pprt->lpAbortProc, (LPSTR)NULL);
if (Escape(pprt->hPr, STARTDOC, strlen(pprt->pcszName) + 1, pprt->pcszName, (LPSTR)NULL) < 0)
goto ERROR_EXIT;
// Create the Abort dialog box (modeless)
pprt->hAbortDlgWnd = CreateDialog(WindowsInstance(), "AbortPrintDlg", GetActiveWindow(), pprt->lpAbortDlg);
if (!pprt->hAbortDlgWnd)
goto ERROR_EXIT;
// Now show Abort dialog
ShowWindow (pprt->hAbortDlgWnd, SW_NORMAL);
SetCursor(pprt->hSaveCursor); // Remove the hourglass
pprt->hSaveCursor = 0;
GetTextMetrics(pprt->hPr, &pprt->textmetric);
pprt->iLineSpace = pprt->textmetric.tmHeight + pprt->textmetric.tmExternalLeading;
pprt->iHorzSize = GetDeviceCaps (pprt->hPr, HORZRES);
pprt->iVertSize = GetDeviceCaps (pprt->hPr, VERTRES);
#endif
//
// Open the input file
//
strcpy(pprt->szFile, pcszFile);
if (!FnameQualify(pprt->szFile, "PRN", EnvGet("TEMP"), FNAME_APP_DIR|FNAME_NO_CREATE)
|| !FnameIsFile(pprt->szFile))
{
Error("Print spool file '%s' not found.", pcszFile);
goto ERROR_EXIT;
}
fsFile = FL_OPEN|FL_READONLY|FL_BINARY;
if (!FileOpen(&pprt->hf, pprt->szFile, fsFile, NULL))
{
Error("Unable to open print spool file '%s'.", pcszFile);
goto ERROR_EXIT;
}
pprt->lSize = FileGetSize(pprt->hf);
if (pprt->lSize < 0)
goto ERROR_EXIT;
_pprt = pprt;
return pprt;
ERROR_EXIT:
pprt->fError = TRUE;
return pprt;
}
#endif
//----------------------------------------------------------------------------
// Description: Process print file
// Parameters:
// Returns: TRUE if successful.
//----------------------------------------------------------------------------
#if OS_DOS || OS_WINDOWS
static BOOL FN_E PrintProcess(PPRT pprt)
{
pprt->pb2 = pprt->bBuf2; // Set pointers to output buffers
pprt->pb3 = pprt->bBuf3;
while ((unsigned)pprt->fpos < pprt->lSize && !pprt->fAbort)
{ // Read a full buffer
pprt->cBuf1 = (SIZET)MIN((FPOS)MAX_PRINT_BUF, (FPOS)(pprt->lSize - pprt->fpos));
if (!FileRead(pprt->hf, pprt->bBuf1, pprt->cBuf1, pprt->fpos))
{
pprt->fError = TRUE;
break;
}
if (!PrintBuffer(pprt)) // Process this buffer
break;
pprt->fpos += (FPOS)pprt->cBuf1; // Move to start of next buffer
}
if (pprt->fCommandPending) // If a command is pending, process it
PrintCommand(pprt);
PrintText(pprt, FALSE); // Process any remaining text
return pprt->fError ? FALSE: TRUE;
}
#endif
//----------------------------------------------------------------------------
// Description:
// Parameters:
// Returns: TRUE if successful.
//----------------------------------------------------------------------------
#if OS_DOS || OS_WINDOWS
static BOOL FN_E PrintTerminate(PPRT pprt)
{
BOOL fError = pprt->fError;
if (fError)
Log(LOG_LOW, "'%s' printed successfully.", pprt->szFile);
else
Log(LOG_LOW, "'%s' printing failed.", pprt->szFile);
if (pprt->hf >= 0) // Close input file
FileClose(pprt->hf);
// Delete spool file
if (BTEST(pprt->fs, PRT_DELETE_SPOOL))
FnameDelete(pprt->szFile);
#if OS_WINDOWS
if (pprt->iStatus >= 0 // Flush last page!
&& pprt->fPagePending
&& !pprt->fAbort)
Escape(pprt->hPr, NEWFRAME, 0, 0L, 0L);
if (pprt->hPr)
{
Escape(pprt->hPr, ENDDOC, 0, 0L, 0L);
DeleteDC(pprt->hPr);
}
if (pprt->hAbortDlgWnd)
DestroyWindow(pprt->hAbortDlgWnd);
if (pprt->lpAbortDlg)
FreeProcInstance((FARPROC)pprt->lpAbortDlg);
if (pprt->lpAbortProc)
FreeProcInstance(pprt->lpAbortProc);
if (pprt->hSaveCursor)
SetCursor(pprt->hSaveCursor); // Remove the hourglass
#else
if (!PrintFFDos(pprt)) // Goto next page
return FALSE;
#endif
MemFree(pprt);
_pprt = NULL;
return fError ? FALSE: TRUE;
}
#endif
//----------------------------------------------------------------------------
// Description:
// Parameters:
// Returns: TRUE if successful.
//----------------------------------------------------------------------------
#if OS_DOS || OS_WINDOWS
static BOOL FN_E PrintText(PPRT pprt, BOOL fLf)
{
PSZ psz1;
*pprt->pb2 = '\0'; // Add null terminator
psz1 = (PSZ)pprt->bBuf2;
if (fLf || psz1[0]) // If forced linefeed or text pending
{
#if OS_DOS
if (!PrintTextDos(pprt))
return FALSE;
#elif OS_WINDOWS
if (!PrintTextWindows(pprt))
return FALSE;
#endif
}
pprt->pb2 = pprt->bBuf2;
return TRUE;
}
#endif
//----------------------------------------------------------------------------
// Description: Print a buffer of text under DOS
// Parameters:
// Returns: TRUE if successful.
//----------------------------------------------------------------------------
#if OS_DOS
static BOOL FN_E PrintFFDos(PPRT pprt)
{
USHORT us1;
us1 = DosPrintLine("\f", pprt->usPort);
if (us1)
{
pprt->fError = TRUE;
return FALSE;
}
return TRUE;
}
#endif
//----------------------------------------------------------------------------
// Description: Print a buffer of text under DOS
// Parameters:
// Returns: TRUE if successful.
//----------------------------------------------------------------------------
#if OS_DOS
static BOOL FN_E PrintTextDos(PPRT pprt)
{
USHORT us1, us2;
us1 = DosPrintLine((PSZ)pprt->bBuf2, pprt->usPort);
us2 = DosPrintLine("\r\n", pprt->usPort);
if (us1 || us2)
{
pprt->fError = TRUE;
return FALSE;
}
return TRUE;
}
#endif
//----------------------------------------------------------------------------
// Description:
// Parameters:
// Returns: TRUE if successful.
//----------------------------------------------------------------------------
#if OS_WINDOWS
static BOOL FN_E PrintFFWindows(PPRT pprt)
{
if (pprt->iStatus >= 0 // Flush current page
&& !pprt->fAbort)
pprt->iStatus = Escape(pprt->hPr, NEWFRAME, 0, 0L, 0L);
pprt->fPagePending = FALSE;
return TRUE;
}
#endif
//----------------------------------------------------------------------------
// Description:
// Parameters:
// Returns: TRUE if successful.
//----------------------------------------------------------------------------
#if OS_WINDOWS
static BOOL FN_E PrintTextWindows(PPRT pprt)
{
PSZ psz1 = (PSZ)pprt->bBuf2;
RECT rect;
INT iHeight;
WORD wFlags;
rect.left = 0;
rect.top = pprt->iTop;
rect.right = pprt->iHorzSize - 1;
rect.bottom = pprt->iVertSize - pprt->iTop - 1;
wFlags = DT_LEFT|DT_EXPANDTABS|DT_NOPREFIX|DT_WORDBREAK;
iHeight = DrawText(pprt->hPr, psz1, -1, &rect, wFlags|DT_CALCRECT);
if (pprt->iTop &&
iHeight > pprt->iVertSize - pprt->iTop - 1)
{
if (pprt->iStatus >= 0 // Flush current page
&& !pprt->fAbort)
pprt->iStatus = Escape(pprt->hPr, NEWFRAME, 0, 0L, 0L);
pprt->iTop = 0; // Recurse 1 level
return PrintTextWindows(pprt);
}
if (pprt->iStatus < 0)
pprt->fError = TRUE;
pprt->fPagePending = TRUE;
DrawText(pprt->hPr, psz1, -1, &rect, wFlags);
pprt->iTop += iHeight;
return !pprt->fError;
}
#endif
//----------------------------------------------------------------------------
// Description:
// Parameters:
// Returns: TRUE if successful.
//----------------------------------------------------------------------------
#if OS_WINDOWS
static int FN_W WindowsAbortDlg(HWND hDlg, unsigned msg, WORD wParam, LONG lParam)
{
NOTUSED(wParam);
NOTUSED(lParam);
switch(msg)
{
case WM_COMMAND: // Watch for Cancel button, RETURN key,
if (_pprt) // ESCAPE key, or SPACE BAR
_pprt->fAbort = TRUE;
return TRUE;
case WM_INITDIALOG: // Set the focus to the Cancel box of the dialog
{
RECT rectDesk, rect; // Center the dialog
INT x, y, cx, cy;
GetWindowRect(GetDesktopWindow(), &rectDesk);
GetWindowRect(hDlg, &rect);
cx = rect.right - rect.left + 1;
cy = rect.bottom - rect.top + 1;
x = ((rectDesk.right - rectDesk.left + 1) - cx) / 2;
y = ((rectDesk.bottom - rectDesk.top + 1) - cy) / 2;
SetWindowPos(hDlg, (HWND)NULL, x, y, cx, cy, SWP_NOZORDER|SWP_NOACTIVATE);
// Set focus to cancel button
SetFocus(GetDlgItem(hDlg, IDCANCEL));
}
return TRUE;
}
return FALSE;
}
#endif
//----------------------------------------------------------------------------
// Description:
// Parameters:
// Returns: TRUE if successful.
//----------------------------------------------------------------------------
#if OS_WINDOWS
static int FN_W WindowsAbortProc(HDC hPr, int iCode)
{
MSG msg;
NOTUSED(hPr);
NOTUSED(iCode);
if (_pprt == NULL // If not initialized correctly
|| !_pprt->hAbortDlgWnd) // If the abort dialog isn't up yet
return TRUE;
//
// Process messages intended for the abort dialog box
//
while (!_pprt->fAbort && PeekMessage(&msg, NULL, 0/*NULL*/, 0/*NULL*/, TRUE))
{
if (!IsDialogMessage(_pprt->hAbortDlgWnd, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return !_pprt->fAbort; // Has the user has aborted?
}
#endif
//----------------------------------------------------------------------------
// Description:
// Parameters:
// Returns:
//----------------------------------------------------------------------------
#if OS_WINDOWS
static HDC FN_L WindowsGetPrinterDC(PPRT pprt)
{
HDC hDC;
LPDEVMODE lpDevMode = NULL;
LPDEVNAMES lpDevNames;
LPSTR lpszDriverName;
LPSTR lpszDeviceName;
LPSTR lpszPortName;
if (!PrintDlg((LPPRINTDLG)&pprt->pd))
return NULL;
if (pprt->pd.hDC)
hDC = pprt->pd.hDC;
else
{
if (!pprt->pd.hDevNames)
{
Error("No printer device found.");
pprt->fError = TRUE;
return NULL;
}
lpDevNames = (LPDEVNAMES)GlobalLock(pprt->pd.hDevNames);
lpszDriverName = (LPSTR)lpDevNames + lpDevNames->wDriverOffset;
lpszDeviceName = (LPSTR)lpDevNames + lpDevNames->wDeviceOffset;
lpszPortName = (LPSTR)lpDevNames + lpDevNames->wOutputOffset;
GlobalUnlock(pprt->pd.hDevNames);
if (pprt->pd.hDevMode)
lpDevMode = (LPDEVMODE)GlobalLock(pprt->pd.hDevMode);
hDC = CreateDC(lpszDriverName, lpszDeviceName, lpszPortName, (LPSTR)lpDevMode);
if (pprt->pd.hDevMode && lpDevMode)
GlobalUnlock(pprt->pd.hDevMode);
}
if (pprt->pd.hDevNames)
{
GlobalFree(pprt->pd.hDevNames);
pprt->pd.hDevNames = NULL;
}
if (pprt->pd.hDevMode)
{
GlobalFree(pprt->pd.hDevMode);
pprt->pd.hDevMode=NULL;
}
return hDC;
}
#endif
//----------------------------------------------------------------------------
// Description: Run standard test suite
// Parameters: sTest Test to run.
// 0 Run all default tests (except).
// Returns: TRUE if successful.
//----------------------------------------------------------------------------
#if COMPILE_TEST
BOOL FN PrintTest(SHORT sTest)
{
NOTUSED(sTest);
#if OS_DOS || OS_WINDOWS
return PrintFile("\\config.sys", 0, NULL, NULL);
#else
return TRUE;
#endif
}
#endif
//----------------------------------------------------------------------------
//------------------------------- End of File --------------------------------
//----------------------------------------------------------------------------